﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO;

namespace QnD_Empty_Directory_Remover
{
    public partial class mainform : Form
    {
        public mainform()
        {
            InitializeComponent();
            CheckForIllegalCrossThreadCalls = false; //CBA to delegate everything, we're only calling labels from one other thread anyway, not really that exciting.
            checkedListBox_emptydirs.MouseDoubleClick += new MouseEventHandler(checkedListBox_emptydirs_MouseDoubleClick);
        }

        void checkedListBox_emptydirs_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            System.Diagnostics.Process p = new System.Diagnostics.Process();
            p.StartInfo = new System.Diagnostics.ProcessStartInfo() {FileName = "explorer.exe", Arguments = "\\select," + checkedListBox_emptydirs.SelectedItem.ToString() };
            p.Start();
        }

        #region variables

        public List<DirectoryInfo> directories = new List<DirectoryInfo>();
        public List<DirectoryInfo> emptydirs = new List<DirectoryInfo>();
        public int noaccess = 0;
        public int skipped = 0;
        public DateTime starttime = new DateTime();

        #endregion


        #region buttonactions
        private void button_browse_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                textbox_folder.Text = fbd.SelectedPath;
            }
        }

        private void button_startsearch_Click(object sender, EventArgs e)
        {
            directories = new List<DirectoryInfo>();
            emptydirs = new List<DirectoryInfo>();
            noaccess = 0;
            skipped = 0;
            checkedListBox_emptydirs.Items.Clear();
            panel_buttons.Enabled = false;
            starttime = DateTime.Now;
            ThreadPool.QueueUserWorkItem(new WaitCallback(findemptydirs));
        }

        private void button_deleteselected_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("I'm going to delete all the directories you checked in the listbox.\n\nSometimes empty directories are needed.\nI'm assuming you know what it means if you delete an empty directory\nI am in no way responsible for you crashing windows or applications within windows due to them unable to find directories they need to store e.g temp files in.\n\nUSE AT OWN RISK.\n\n\n Proceed?", "Are you SURE?", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == System.Windows.Forms.DialogResult.Yes)
            {
                foreach (var dirtodelete in checkedListBox_emptydirs.CheckedItems)
                {
                    Directory.Delete(dirtodelete.ToString());
                }
                checkedListBox_emptydirs.Items.Clear();
                MessageBox.Show("Done. Listbox has been emptied to prevent errors; Don't worry, only the selected directories were removed.\nIf you wish to select more directories, just hit 'Start search' again.", "Done!", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void button_selectall_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < checkedListBox_emptydirs.Items.Count; i++)
            {
                checkedListBox_emptydirs.SetItemChecked(i, true);
            }
        }

        #endregion

        #region delegates
        public void getdirectories(string path)
        {
            try
            {
                string[] dirs = Directory.GetDirectories(path);
                dirs.ToList().ForEach(s => directories.Add(new DirectoryInfo(s)));
                dirs.ToList().ForEach(s => getdirectories(s));
            }
            catch (UnauthorizedAccessException)
            {
                // ok, so we are not allowed to dig into that directory. Move on.
                noaccess++;
            }
            catch (Exception)
            {
                skipped++;

            }
            if ((directories.Count % 10) == 0)
            {
                label_totaldirs.Text = "Directories: " + directories.Count.ToString();
                label_skipped.Text = "Skipped: " + skipped.ToString();
                label_accessdenied.Text = "Access Denied: " + noaccess.ToString();
                label_timespent.Text = "Time spent:\n" + (DateTime.Now - starttime).TotalSeconds.ToString() + " Seconds";
            }
        }

        delegate void addtolistdelegate();

        DirectoryInfo curemptydir;
        public void addlistitem()
        {
            DirectoryInfo dirinfo = curemptydir;
            checkedListBox_emptydirs.Items.Add(dirinfo.FullName);
        }

        #endregion

        #region functions
        public void findemptydirs(object blargh)
        {
            getdirectories(textbox_folder.Text);

            foreach (var dir in directories)
            {
                try
                {
                    if (dir.GetFileSystemInfos().Length < 1)
                    {

                        emptydirs.Add(dir);
                        curemptydir = dir;
                        if (checkedListBox_emptydirs.InvokeRequired)
                        {
                            addtolistdelegate additem = new addtolistdelegate(addlistitem);
                            checkedListBox_emptydirs.Invoke(additem);
                        }
                        else
                        {
                            addlistitem();
                        }
                        if ((emptydirs.Count % 10) == 0)
                        {
                            label_emptydirs.Text = "Empty directories: " + emptydirs.Count.ToString();
                        }
                    }
                }
                catch (UnauthorizedAccessException)
                {
                    noaccess++;
                    label_accessdenied.Text = "Access Denied: " + noaccess.ToString();
                }
                catch (Exception)
                {
                    skipped++;
                    label_skipped.Text = "Skipped: " + skipped.ToString();
                }

            }

            label_emptydirs.Text = "Empty directories: " + emptydirs.Count.ToString();
            label_totaldirs.Text = "Directories: " + directories.Count.ToString();
            label_skipped.Text = "Skipped: " + skipped.ToString();
            label_accessdenied.Text = "Access Denied: " + noaccess.ToString();
            label_timespent.Text = "Time spent:\n" + (DateTime.Now - starttime).TotalSeconds.ToString() + " Seconds";

            panel_buttons.Enabled = true;

        }

        #endregion




    }
}
